1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.truth.Truth.assertThat;
20  import static java.util.Arrays.asList;
21  
22  import com.google.common.annotations.GwtCompatible;
23  
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.Comparator;
28  import java.util.Iterator;
29  import java.util.NoSuchElementException;
30  import java.util.Set;
31  import java.util.SortedSet;
32  import java.util.TreeSet;
33  
34  /**
35   * Unit tests for {@link ImmutableSortedSet}.
36   *
37   * @author Jared Levy
38   */
39  @GwtCompatible(emulated = true)
40  public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
41  
42    // enum singleton pattern
43    private enum StringLengthComparator implements Comparator<String> {
44      INSTANCE;
45  
46      @Override
47      public int compare(String a, String b) {
48        return a.length() - b.length();
49      }
50    }
51  
52    private static final Comparator<String> STRING_LENGTH
53        = StringLengthComparator.INSTANCE;
54  
55    @Override protected SortedSet<String> of() {
56      return ImmutableSortedSet.of();
57    }
58  
59    @Override protected SortedSet<String> of(String e) {
60      return ImmutableSortedSet.of(e);
61    }
62  
63    @Override protected SortedSet<String> of(String e1, String e2) {
64      return ImmutableSortedSet.of(e1, e2);
65    }
66  
67    @Override protected SortedSet<String> of(String e1, String e2, String e3) {
68      return ImmutableSortedSet.of(e1, e2, e3);
69    }
70  
71    @Override protected SortedSet<String> of(
72        String e1, String e2, String e3, String e4) {
73      return ImmutableSortedSet.of(e1, e2, e3, e4);
74    }
75  
76    @Override protected SortedSet<String> of(
77        String e1, String e2, String e3, String e4, String e5) {
78      return ImmutableSortedSet.of(e1, e2, e3, e4, e5);
79    }
80  
81    @Override protected SortedSet<String> of(String e1, String e2, String e3,
82        String e4, String e5, String e6, String... rest) {
83      return ImmutableSortedSet.of(e1, e2, e3, e4, e5, e6, rest);
84    }
85  
86    @Override protected SortedSet<String> copyOf(String[] elements) {
87      return ImmutableSortedSet.copyOf(elements);
88    }
89  
90    @Override protected SortedSet<String> copyOf(Collection<String> elements) {
91      return ImmutableSortedSet.copyOf(elements);
92    }
93  
94    @Override protected SortedSet<String> copyOf(Iterable<String> elements) {
95      return ImmutableSortedSet.copyOf(elements);
96    }
97  
98    @Override protected SortedSet<String> copyOf(Iterator<String> elements) {
99      return ImmutableSortedSet.copyOf(elements);
100   }
101 
102   public void testEmpty_comparator() {
103     SortedSet<String> set = of();
104     assertSame(Ordering.natural(), set.comparator());
105   }
106 
107   public void testEmpty_headSet() {
108     SortedSet<String> set = of();
109     assertSame(set, set.headSet("c"));
110   }
111 
112   public void testEmpty_tailSet() {
113     SortedSet<String> set = of();
114     assertSame(set, set.tailSet("f"));
115   }
116 
117   public void testEmpty_subSet() {
118     SortedSet<String> set = of();
119     assertSame(set, set.subSet("c", "f"));
120   }
121 
122   public void testEmpty_first() {
123     SortedSet<String> set = of();
124     try {
125       set.first();
126       fail();
127     } catch (NoSuchElementException expected) {
128     }
129   }
130 
131   public void testEmpty_last() {
132     SortedSet<String> set = of();
133     try {
134       set.last();
135       fail();
136     } catch (NoSuchElementException expected) {
137     }
138   }
139 
140   public void testSingle_comparator() {
141     SortedSet<String> set = of("e");
142     assertSame(Ordering.natural(), set.comparator());
143   }
144 
145   public void testSingle_headSet() {
146     SortedSet<String> set = of("e");
147     assertTrue(set.headSet("g") instanceof ImmutableSortedSet);
148     assertThat(set.headSet("g")).has().item("e");
149     assertSame(of(), set.headSet("c"));
150     assertSame(of(), set.headSet("e"));
151   }
152 
153   public void testSingle_tailSet() {
154     SortedSet<String> set = of("e");
155     assertTrue(set.tailSet("c") instanceof ImmutableSortedSet);
156     assertThat(set.tailSet("c")).has().item("e");
157     assertThat(set.tailSet("e")).has().item("e");
158     assertSame(of(), set.tailSet("g"));
159   }
160 
161   public void testSingle_subSet() {
162     SortedSet<String> set = of("e");
163     assertTrue(set.subSet("c", "g") instanceof ImmutableSortedSet);
164     assertThat(set.subSet("c", "g")).has().item("e");
165     assertThat(set.subSet("e", "g")).has().item("e");
166     assertSame(of(), set.subSet("f", "g"));
167     assertSame(of(), set.subSet("c", "e"));
168     assertSame(of(), set.subSet("c", "d"));
169   }
170 
171   public void testSingle_first() {
172     SortedSet<String> set = of("e");
173     assertEquals("e", set.first());
174   }
175 
176   public void testSingle_last() {
177     SortedSet<String> set = of("e");
178     assertEquals("e", set.last());
179   }
180 
181   public void testOf_ordering() {
182     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
183     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
184   }
185 
186   /*
187    * Tests that we workaround GWT bug #3621 (or that it is already fixed).
188    *
189    * A call to of() with a parameter that is not a plain Object[] (here,
190    * Interface[]) creates a RegularImmutableSortedSet backed by an array of that
191    * type. Later, RegularImmutableSortedSet.toArray() calls System.arraycopy()
192    * to copy from that array to the destination array. This would be fine, but
193    * GWT has a bug: It refuses to copy from an E[] to an Object[] when E is an
194    * interface type.
195    */
196   // TODO: test other collections for this problem
197   public void testOf_gwtArraycopyBug() {
198     /*
199      * The test requires:
200      *
201      * 1) An interface I extending Comparable<I> so that the created array is of
202      * an interface type. 2) An instance of a class implementing that interface
203      * so that we can pass non-null instances of the interface.
204      *
205      * (Currently it's safe to pass instances for which compareTo() always
206      * returns 0, but if we had a SingletonImmutableSortedSet, this might no
207      * longer be the case.)
208      *
209      * javax.naming.Name and java.util.concurrent.Delayed might work, but
210      * they're fairly obscure, we've invented our own interface and class.
211      */
212     Interface a = new Impl();
213     Interface b = new Impl();
214     ImmutableSortedSet<Interface> set = ImmutableSortedSet.of(a, b);
215     set.toArray();
216     set.toArray(new Object[2]);
217   }
218 
219   interface Interface extends Comparable<Interface> {
220   }
221   static class Impl implements Interface {
222     static int nextId;
223     Integer id = nextId++;
224 
225     @Override public int compareTo(Interface other) {
226       return id.compareTo(((Impl) other).id);
227     }
228   }
229 
230   public void testOf_ordering_dupes() {
231     SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c");
232     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
233   }
234 
235   public void testOf_comparator() {
236     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
237     assertSame(Ordering.natural(), set.comparator());
238   }
239 
240   public void testOf_headSet() {
241     SortedSet<String> set = of("e", "f", "b", "d", "c");
242     assertTrue(set.headSet("e") instanceof ImmutableSortedSet);
243     assertThat(set.headSet("e")).has().exactly("b", "c", "d").inOrder();
244     assertThat(set.headSet("g")).has().exactly("b", "c", "d", "e", "f").inOrder();
245     assertSame(of(), set.headSet("a"));
246     assertSame(of(), set.headSet("b"));
247   }
248 
249   public void testOf_tailSet() {
250     SortedSet<String> set = of("e", "f", "b", "d", "c");
251     assertTrue(set.tailSet("e") instanceof ImmutableSortedSet);
252     assertThat(set.tailSet("e")).has().exactly("e", "f").inOrder();
253     assertThat(set.tailSet("a")).has().exactly("b", "c", "d", "e", "f").inOrder();
254     assertSame(of(), set.tailSet("g"));
255   }
256 
257   public void testOf_subSet() {
258     SortedSet<String> set = of("e", "f", "b", "d", "c");
259     assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet);
260     assertThat(set.subSet("c", "e")).has().exactly("c", "d").inOrder();
261     assertThat(set.subSet("a", "g")).has().exactly("b", "c", "d", "e", "f").inOrder();
262     assertSame(of(), set.subSet("a", "b"));
263     assertSame(of(), set.subSet("g", "h"));
264     assertSame(of(), set.subSet("c", "c"));
265     try {
266       set.subSet("e", "c");
267       fail();
268     } catch (IllegalArgumentException expected) {
269     }
270   }
271 
272   public void testOf_first() {
273     SortedSet<String> set = of("e", "f", "b", "d", "c");
274     assertEquals("b", set.first());
275   }
276 
277   public void testOf_last() {
278     SortedSet<String> set = of("e", "f", "b", "d", "c");
279     assertEquals("f", set.last());
280   }
281 
282   /* "Explicit" indicates an explicit comparator. */
283 
284   public void testExplicit_ordering() {
285     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
286         "in", "the", "quick", "jumped", "over", "a").build();
287     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
288   }
289 
290   public void testExplicit_ordering_dupes() {
291     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
292         "in", "the", "quick", "brown", "fox", "jumped",
293         "over", "a", "lazy", "dog").build();
294     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
295   }
296 
297   public void testExplicit_contains() {
298     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
299         "in", "the", "quick", "jumped", "over", "a").build();
300     assertTrue(set.contains("quick"));
301     assertTrue(set.contains("google"));
302     assertFalse(set.contains(""));
303     assertFalse(set.contains("california"));
304     assertFalse(set.contains(null));
305   }
306 
307   public void testExplicit_containsMismatchedTypes() {
308     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
309         "in", "the", "quick", "jumped", "over", "a").build();
310     assertFalse(set.contains(3.7));
311   }
312 
313   public void testExplicit_comparator() {
314     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
315         "in", "the", "quick", "jumped", "over", "a").build();
316     assertSame(STRING_LENGTH, set.comparator());
317   }
318 
319   public void testExplicit_headSet() {
320     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
321         "in", "the", "quick", "jumped", "over", "a").build();
322     assertTrue(set.headSet("a") instanceof ImmutableSortedSet);
323     assertTrue(set.headSet("fish") instanceof ImmutableSortedSet);
324     assertThat(set.headSet("fish")).has().exactly("a", "in", "the").inOrder();
325     assertThat(set.headSet("california")).has()
326         .exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
327     assertTrue(set.headSet("a").isEmpty());
328     assertTrue(set.headSet("").isEmpty());
329   }
330 
331   public void testExplicit_tailSet() {
332     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
333         "in", "the", "quick", "jumped", "over", "a").build();
334     assertTrue(set.tailSet("california") instanceof ImmutableSortedSet);
335     assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet);
336     assertThat(set.tailSet("fish")).has().exactly("over", "quick", "jumped").inOrder();
337     assertThat(
338         set.tailSet("a")).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
339     assertTrue(set.tailSet("california").isEmpty());
340   }
341 
342   public void testExplicit_subSet() {
343     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
344         "in", "the", "quick", "jumped", "over", "a").build();
345     assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet);
346     assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet);
347     assertThat(set.subSet("the", "quick")).has().exactly("the", "over").inOrder();
348     assertThat(set.subSet("a", "california"))
349         .has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
350     assertTrue(set.subSet("", "b").isEmpty());
351     assertTrue(set.subSet("vermont", "california").isEmpty());
352     assertTrue(set.subSet("aaa", "zzz").isEmpty());
353     try {
354       set.subSet("quick", "the");
355       fail();
356     } catch (IllegalArgumentException expected) {
357     }
358   }
359 
360   public void testExplicit_first() {
361     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
362         "in", "the", "quick", "jumped", "over", "a").build();
363     assertEquals("a", set.first());
364   }
365 
366   public void testExplicit_last() {
367     SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
368         "in", "the", "quick", "jumped", "over", "a").build();
369     assertEquals("jumped", set.last());
370   }
371 
372   public void testCopyOf_ordering() {
373     SortedSet<String> set =
374         copyOf(asList("e", "a", "f", "b", "d", "c"));
375     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
376   }
377 
378   public void testCopyOf_ordering_dupes() {
379     SortedSet<String> set =
380         copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c"));
381     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
382   }
383 
384   public void testCopyOf_subSet() {
385     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
386     SortedSet<String> subset = set.subSet("c", "e");
387     SortedSet<String> copy = copyOf(subset);
388     assertEquals(subset, copy);
389   }
390 
391   public void testCopyOf_headSet() {
392     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
393     SortedSet<String> headset = set.headSet("d");
394     SortedSet<String> copy = copyOf(headset);
395     assertEquals(headset, copy);
396   }
397 
398   public void testCopyOf_tailSet() {
399     SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
400     SortedSet<String> tailset = set.tailSet("d");
401     SortedSet<String> copy = copyOf(tailset);
402     assertEquals(tailset, copy);
403   }
404 
405   public void testCopyOf_comparator() {
406     SortedSet<String> set = copyOf(asList("e", "a", "f", "b", "d", "c"));
407     assertSame(Ordering.natural(), set.comparator());
408   }
409 
410   public void testCopyOf_iterator_ordering() {
411     SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
412     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
413   }
414 
415   public void testCopyOf_iterator_ordering_dupes() {
416     SortedSet<String> set =
417         copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c"));
418     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
419   }
420 
421   public void testCopyOf_iterator_comparator() {
422     SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
423     assertSame(Ordering.natural(), set.comparator());
424   }
425 
426   public void testCopyOf_sortedSet_ordering() {
427     SortedSet<String> set =
428         copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c")));
429     assertThat(set).has().exactly("a", "b", "c", "d", "e", "f").inOrder();
430   }
431 
432   public void testCopyOf_sortedSet_comparator() {
433     SortedSet<String> set = copyOf(Sets.<String>newTreeSet());
434     assertSame(Ordering.natural(), set.comparator());
435   }
436 
437   public void testCopyOfExplicit_ordering() {
438     SortedSet<String> set =
439         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
440             "in", "the", "quick", "jumped", "over", "a"));
441     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
442   }
443 
444   public void testCopyOfExplicit_ordering_dupes() {
445     SortedSet<String> set =
446         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
447             "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
448             "lazy", "dog"));
449     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
450   }
451 
452   public void testCopyOfExplicit_comparator() {
453     SortedSet<String> set =
454         ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
455             "in", "the", "quick", "jumped", "over", "a"));
456     assertSame(STRING_LENGTH, set.comparator());
457   }
458 
459   public void testCopyOfExplicit_iterator_ordering() {
460     SortedSet<String> set =
461         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
462             "in", "the", "quick", "jumped", "over", "a"));
463     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
464   }
465 
466   public void testCopyOfExplicit_iterator_ordering_dupes() {
467     SortedSet<String> set =
468         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
469             "in", "the", "quick", "brown", "fox", "jumped", "over", "a",
470             "lazy", "dog"));
471     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
472   }
473 
474   public void testCopyOfExplicit_iterator_comparator() {
475     SortedSet<String> set =
476         ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
477             "in", "the", "quick", "jumped", "over", "a"));
478     assertSame(STRING_LENGTH, set.comparator());
479   }
480 
481   public void testCopyOf_sortedSetIterable() {
482     SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
483     Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
484     SortedSet<String> set = copyOf(input);
485     assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
486   }
487 
488   public void testCopyOfSorted_natural_ordering() {
489     SortedSet<String> input = Sets.newTreeSet(
490         asList("in", "the", "quick", "jumped", "over", "a"));
491     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
492     assertThat(set).has().exactly("a", "in", "jumped", "over", "quick", "the").inOrder();
493   }
494 
495   public void testCopyOfSorted_natural_comparator() {
496     SortedSet<String> input =
497         Sets.newTreeSet(asList("in", "the", "quick", "jumped", "over", "a"));
498     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
499     assertSame(Ordering.natural(), set.comparator());
500   }
501 
502   public void testCopyOfSorted_explicit_ordering() {
503     SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
504     Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
505     SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
506     assertThat(set).has().exactly("a", "in", "the", "over", "quick", "jumped").inOrder();
507     assertSame(STRING_LENGTH, set.comparator());
508   }
509 
510   public void testEquals_bothDefaultOrdering() {
511     SortedSet<String> set = of("a", "b", "c");
512     assertEquals(set, Sets.newTreeSet(asList("a", "b", "c")));
513     assertEquals(Sets.newTreeSet(asList("a", "b", "c")), set);
514     assertFalse(set.equals(Sets.newTreeSet(asList("a", "b", "d"))));
515     assertFalse(Sets.newTreeSet(asList("a", "b", "d")).equals(set));
516     assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
517     assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
518   }
519 
520   public void testEquals_bothExplicitOrdering() {
521     SortedSet<String> set = of("in", "the", "a");
522     assertEquals(Sets.newTreeSet(asList("in", "the", "a")), set);
523     assertFalse(set.equals(Sets.newTreeSet(asList("in", "the", "house"))));
524     assertFalse(Sets.newTreeSet(asList("in", "the", "house")).equals(set));
525     assertFalse(set.equals(Sets.newHashSet(4, 5, 6)));
526     assertFalse(Sets.newHashSet(4, 5, 6).equals(set));
527 
528     Set<String> complex = Sets.newTreeSet(STRING_LENGTH);
529     Collections.addAll(complex, "in", "the", "a");
530     assertEquals(set, complex);
531   }
532 
533   public void testEquals_bothDefaultOrdering_StringVsInt() {
534     SortedSet<String> set = of("a", "b", "c");
535     assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
536     assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
537   }
538 
539   public void testEquals_bothExplicitOrdering_StringVsInt() {
540     SortedSet<String> set = of("in", "the", "a");
541     assertFalse(set.equals(Sets.newTreeSet(asList(4, 5, 6))));
542     assertNotEqualLenient(Sets.newTreeSet(asList(4, 5, 6)), set);
543   }
544 
545   public void testContainsAll_notSortedSet() {
546     SortedSet<String> set = of("a", "b", "f");
547     assertTrue(set.containsAll(Collections.emptyList()));
548     assertTrue(set.containsAll(asList("b")));
549     assertTrue(set.containsAll(asList("b", "b")));
550     assertTrue(set.containsAll(asList("b", "f")));
551     assertTrue(set.containsAll(asList("b", "f", "a")));
552     assertFalse(set.containsAll(asList("d")));
553     assertFalse(set.containsAll(asList("z")));
554     assertFalse(set.containsAll(asList("b", "d")));
555     assertFalse(set.containsAll(asList("f", "d", "a")));
556   }
557 
558   public void testContainsAll_sameComparator() {
559     SortedSet<String> set = of("a", "b", "f");
560     assertTrue(set.containsAll(Sets.newTreeSet()));
561     assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
562     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
563     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
564     assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
565     assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
566     assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
567     assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
568   }
569 
570   public void testContainsAll_sameComparator_StringVsInt() {
571     SortedSet<String> set = of("a", "b", "f");
572     SortedSet<Integer> unexpected = Sets.newTreeSet(Ordering.natural());
573     unexpected.addAll(asList(1, 2, 3));
574     assertFalse(set.containsAll(unexpected));
575   }
576 
577   public void testContainsAll_differentComparator() {
578     Comparator<Comparable<?>> comparator = Collections.reverseOrder();
579     SortedSet<String> set = new ImmutableSortedSet.Builder<String>(comparator)
580         .add("a", "b", "f").build();
581     assertTrue(set.containsAll(Sets.newTreeSet()));
582     assertTrue(set.containsAll(Sets.newTreeSet(asList("b"))));
583     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "f"))));
584     assertTrue(set.containsAll(Sets.newTreeSet(asList("a", "b", "f"))));
585     assertFalse(set.containsAll(Sets.newTreeSet(asList("d"))));
586     assertFalse(set.containsAll(Sets.newTreeSet(asList("z"))));
587     assertFalse(set.containsAll(Sets.newTreeSet(asList("b", "d"))));
588     assertFalse(set.containsAll(Sets.newTreeSet(asList("f", "d", "a"))));
589   }
590 
591   public void testReverseOrder() {
592     SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder()
593         .add("a", "b", "c").build();
594     assertThat(set).has().exactly("c", "b", "a").inOrder();
595     assertEquals(Ordering.natural().reverse(), set.comparator());
596   }
597 
598   private static final Comparator<Object> TO_STRING
599       = new Comparator<Object>() {
600           @Override
601           public int compare(Object o1, Object o2) {
602             return o1.toString().compareTo(o2.toString());
603           }
604         };
605 
606   public void testSupertypeComparator() {
607     SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING)
608         .add(3, 12, 101, 44).build();
609     assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
610   }
611 
612   public void testSupertypeComparatorSubtypeElements() {
613     SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING)
614         .add(3, 12, 101, 44).build();
615     assertThat(set).has().exactly(101, 12, 3, 44).inOrder();
616   }
617 
618   @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() {
619     return ImmutableSortedSet.naturalOrder();
620   }
621 
622   @Override int getComplexBuilderSetLastElement() {
623     return 0x00FFFFFF;
624   }
625 
626   public void testLegacyComparable_of() {
627     ImmutableSortedSet<LegacyComparable> set0 = ImmutableSortedSet.of();
628 
629     @SuppressWarnings("unchecked") // using a legacy comparable
630     ImmutableSortedSet<LegacyComparable> set1 = ImmutableSortedSet.of(
631         LegacyComparable.Z);
632 
633     @SuppressWarnings("unchecked") // using a legacy comparable
634     ImmutableSortedSet<LegacyComparable> set2 = ImmutableSortedSet.of(
635         LegacyComparable.Z, LegacyComparable.Y);
636   }
637 
638   public void testLegacyComparable_copyOf_collection() {
639     ImmutableSortedSet<LegacyComparable> set
640         = ImmutableSortedSet.copyOf(LegacyComparable.VALUES_BACKWARD);
641     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
642   }
643 
644   public void testLegacyComparable_copyOf_iterator() {
645     ImmutableSortedSet<LegacyComparable> set = ImmutableSortedSet.copyOf(
646         LegacyComparable.VALUES_BACKWARD.iterator());
647     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
648   }
649 
650   public void testLegacyComparable_builder_natural() {
651     @SuppressWarnings("unchecked")
652     // Note: IntelliJ wrongly reports an error for this statement
653     ImmutableSortedSet.Builder<LegacyComparable> builder
654         = ImmutableSortedSet.<LegacyComparable>naturalOrder();
655 
656     builder.addAll(LegacyComparable.VALUES_BACKWARD);
657     builder.add(LegacyComparable.X);
658     builder.add(LegacyComparable.Y, LegacyComparable.Z);
659 
660     ImmutableSortedSet<LegacyComparable> set = builder.build();
661     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_FORWARD, set));
662   }
663 
664   public void testLegacyComparable_builder_reverse() {
665     @SuppressWarnings("unchecked")
666     // Note: IntelliJ wrongly reports an error for this statement
667     ImmutableSortedSet.Builder<LegacyComparable> builder
668         = ImmutableSortedSet.<LegacyComparable>reverseOrder();
669 
670     builder.addAll(LegacyComparable.VALUES_FORWARD);
671     builder.add(LegacyComparable.X);
672     builder.add(LegacyComparable.Y, LegacyComparable.Z);
673 
674     ImmutableSortedSet<LegacyComparable> set = builder.build();
675     assertTrue(Iterables.elementsEqual(LegacyComparable.VALUES_BACKWARD, set));
676   }
677 
678   @SuppressWarnings({"deprecation", "static-access"})
679   public void testBuilderMethod() {
680     try {
681       ImmutableSortedSet.builder();
682       fail();
683     } catch (UnsupportedOperationException expected) {
684     }
685   }
686 
687   public void testAsList() {
688     ImmutableSet<String> set = ImmutableSortedSet.of("a", "e", "i", "o", "u");
689     ImmutableList<String> list = set.asList();
690     assertEquals(ImmutableList.of("a", "e", "i", "o", "u"), list);
691     assertSame(list, ImmutableList.copyOf(set));
692   }
693 
694   public void testSubsetAsList() {
695     ImmutableSet<String> set
696         = ImmutableSortedSet.of("a", "e", "i", "o", "u").subSet("c", "r");
697     ImmutableList<String> list = set.asList();
698     assertEquals(ImmutableList.of("e", "i", "o"), list);
699     assertEquals(list, ImmutableList.copyOf(set));
700   }
701 
702   public void testAsListInconsistentComprator() {
703     ImmutableSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
704         "in", "the", "quick", "jumped", "over", "a").build();
705     ImmutableList<String> list = set.asList();
706     assertTrue(list.contains("the"));
707     assertEquals(2, list.indexOf("the"));
708     assertEquals(2, list.lastIndexOf("the"));
709     assertFalse(list.contains("dog"));
710     assertEquals(-1, list.indexOf("dog"));
711     assertEquals(-1, list.lastIndexOf("dog"));
712     assertFalse(list.contains("chicken"));
713     assertEquals(-1, list.indexOf("chicken"));
714     assertEquals(-1, list.lastIndexOf("chicken"));
715   }
716 
717   private static <E> Iterator<E> asIterator(E... elements) {
718     return asList(elements).iterator();
719   }
720 
721   // In GWT, java.util.TreeSet throws ClassCastException when the comparator
722   // throws it, unlike JDK6.  Therefore, we accept ClassCastException as a
723   // valid result thrown by java.util.TreeSet#equals.
724   private static void assertNotEqualLenient(
725       TreeSet<?> unexpected, SortedSet<?> actual) {
726     try {
727       assertThat(actual).isNotEqualTo(unexpected);
728     } catch (ClassCastException accepted) {
729     }
730   }
731 
732   public void testHeadSetInclusive() {
733     String[] strings = NUMBER_NAMES.toArray(new String[0]);
734     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
735     Arrays.sort(strings);
736     for (int i = 0; i < strings.length; i++) {
737       assertThat(set.headSet(strings[i], true))
738           .has().exactlyAs(sortedNumberNames(0, i + 1)).inOrder();
739     }
740   }
741 
742   public void testHeadSetExclusive() {
743     String[] strings = NUMBER_NAMES.toArray(new String[0]);
744     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
745     Arrays.sort(strings);
746     for (int i = 0; i < strings.length; i++) {
747       assertThat(set.headSet(strings[i], false)).has().exactlyAs(
748           sortedNumberNames(0, i)).inOrder();
749     }
750   }
751 
752   public void testTailSetInclusive() {
753     String[] strings = NUMBER_NAMES.toArray(new String[0]);
754     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
755     Arrays.sort(strings);
756     for (int i = 0; i < strings.length; i++) {
757       assertThat(set.tailSet(strings[i], true)).has().exactlyAs(
758           sortedNumberNames(i, strings.length)).inOrder();
759     }
760   }
761 
762   public void testTailSetExclusive() {
763     String[] strings = NUMBER_NAMES.toArray(new String[0]);
764     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
765     Arrays.sort(strings);
766     for (int i = 0; i < strings.length; i++) {
767       assertThat(set.tailSet(strings[i], false)).has().exactlyAs(
768           sortedNumberNames(i + 1, strings.length)).inOrder();
769     }
770   }
771 
772   public void testSubSetExclusiveExclusive() {
773     String[] strings = NUMBER_NAMES.toArray(new String[0]);
774     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
775     Arrays.sort(strings);
776     for (int i = 0; i < strings.length; i++) {
777       for (int j = i; j < strings.length; j++) {
778         assertThat(set.subSet(strings[i], false, strings[j], false))
779             .has().exactlyAs(sortedNumberNames(Math.min(i + 1, j), j)).inOrder();
780       }
781     }
782   }
783 
784   public void testSubSetInclusiveExclusive() {
785     String[] strings = NUMBER_NAMES.toArray(new String[0]);
786     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
787     Arrays.sort(strings);
788     for (int i = 0; i < strings.length; i++) {
789       for (int j = i; j < strings.length; j++) {
790         assertThat(set.subSet(strings[i], true, strings[j], false))
791             .has().exactlyAs(sortedNumberNames(i, j)).inOrder();
792       }
793     }
794   }
795 
796   public void testSubSetExclusiveInclusive() {
797     String[] strings = NUMBER_NAMES.toArray(new String[0]);
798     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
799     Arrays.sort(strings);
800     for (int i = 0; i < strings.length; i++) {
801       for (int j = i; j < strings.length; j++) {
802         assertThat(set.subSet(strings[i], false, strings[j], true))
803             .has().exactlyAs(sortedNumberNames(i + 1, j + 1)).inOrder();
804       }
805     }
806   }
807 
808   public void testSubSetInclusiveInclusive() {
809     String[] strings = NUMBER_NAMES.toArray(new String[0]);
810     ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
811     Arrays.sort(strings);
812     for (int i = 0; i < strings.length; i++) {
813       for (int j = i; j < strings.length; j++) {
814         assertThat(set.subSet(strings[i], true, strings[j], true))
815             .has().exactlyAs(sortedNumberNames(i, j + 1)).inOrder();
816       }
817     }
818   }
819 
820   private static ImmutableList<String> sortedNumberNames(int i, int j) {
821     return ImmutableList.copyOf(SORTED_NUMBER_NAMES.subList(i, j));
822   }
823 
824   private static final ImmutableList<String> NUMBER_NAMES =
825       ImmutableList.of("one", "two", "three", "four", "five", "six", "seven");
826 
827   private static final ImmutableList<String> SORTED_NUMBER_NAMES =
828       Ordering.natural().immutableSortedCopy(NUMBER_NAMES);
829 
830   private static class SelfComparableExample implements Comparable<SelfComparableExample> {
831     @Override
832     public int compareTo(SelfComparableExample o) {
833       return 0;
834     }
835   }
836 
837   public void testBuilderGenerics_SelfComparable() {
838     ImmutableSortedSet.Builder<SelfComparableExample> natural = ImmutableSortedSet.naturalOrder();
839     ImmutableSortedSet.Builder<SelfComparableExample> reverse = ImmutableSortedSet.reverseOrder();
840   }
841 
842   private static class SuperComparableExample extends SelfComparableExample {}
843 
844   public void testBuilderGenerics_SuperComparable() {
845     ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder();
846     ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder();
847   }
848 }
849